package org.stephen;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class SweepEngineKit {
    SweepMainFrame sweepMainFrame;
    SweepFinalFrame sweepFinalFrame;
    SweepActionListener sweepActionListener;
    SweepEngineCallBack sweepEngineCallBack;
    JButton[][] buttons;
    int[][] map;
    int[][] router;
    int height;
    int width;
    int boom;
    int finalNum = 0;
    boolean firstClick = true;

    public void createMap(int x,int y) {
        finalNum = SweepEngineKit.this.height*SweepEngineKit.this.width;
        map = new int[SweepEngineKit.this.height][SweepEngineKit.this.width];
        router = new int[SweepEngineKit.this.height][SweepEngineKit.this.width];
        Random random = new Random();
        int boom = SweepEngineKit.this.boom;
        while (boom > 0) {
            int r = random.nextInt(SweepEngineKit.this.height * SweepEngineKit.this.width);
            int h = r / SweepEngineKit.this.width;
            int w = r % SweepEngineKit.this.width;
            if (h!=x && w!=y && map[h][w] == 0) {
                map[h][w] = 1;
                boom--;
            }
        }
        for (int i = 0; i < SweepEngineKit.this.height; i++) {
            for (int j = 0; j < SweepEngineKit.this.width; j++) {
                System.out.print(map[i][j]+"   ");
                if(j==SweepEngineKit.this.width-1) {
                    System.out.println("\n");
                }
            }
        }
    }
    public int getBoomNumAround(int height,int width){
        int num = 0;
        if(height-1>=0){
            num+=map[height-1][width];
        }
        if(width-1>=0){
            num+=map[height][width-1];
        }
        if(width-1>=0 && height-1>=0){
            num+=map[height-1][width-1];
        }
        if(height-1>=0 && width+1<SweepEngineKit.this.width){
            num+=map[height-1][width+1];
        }
        if(width+1<SweepEngineKit.this.width){
            num+=map[height][width+1];
        }
        if(height+1<SweepEngineKit.this.height){
            num+=map[height+1][width];
        }
        if(height+1<SweepEngineKit.this.height && width-1>=0){
            num+=map[height+1][width-1];
        }
        if(height+1<SweepEngineKit.this.height && width+1<SweepEngineKit.this.width){
            num+=map[height+1][width+1];
        }
        return num;
    }

    public void DFS(int height, int width) {
        if (height < 0 || width < 0 || height >= SweepEngineKit.this.height || width >= SweepEngineKit.this.width || this.router[height][width] == 1)
            return;
        if (this.map[height][width] != 1) {
            System.out.println("x:"+width+"y:"+height);
            this.router[height][width] = 1;
            int num = getBoomNumAround(height,width);
            if(num==0){
                buttons[height][width].setText("");//设置内容为空
            }else {
                buttons[height][width].setText(String.valueOf(num));
                buttons[height][width].setFont(new Font("宋体", 1, 20));
                buttons[height][width].setForeground(getColorByNum(num));
            }
            buttons[height][width].setBackground(Color.white);//设置背景为白色
            buttons[height][width].setOpaque(true);
            buttons[height][width].removeActionListener(sweepActionListener);//
            DFS(height + 1, width);
            DFS(height - 1, width);
            DFS(height, width - 1);
            DFS(height, width + 1);
            finalNum--;
            if(finalNum==boom){
                sweepEngineCallBack.success();
            }
        }
    }
    public Color getColorByNum(int num){
        switch (num){
            case 1:
                return Color.RED;
            case 2:
                return Color.BLACK;
            case 3:
                return Color.BLUE;
            case 4:
                return Color.CYAN;
            case 5:
                return Color.GREEN;
            case 6:
                return Color.MAGENTA;
            case 7:
                return Color.ORANGE;
            case 8:
                return Color.YELLOW;
        }
        return Color.white;
    }

    public class SweepMainFrame extends JFrame {
        SweepEngineCallBack sweepEngineCallBack;
        public void init(int level, SweepEngineCallBack sweepEngineCallBack, SweepActionListener sweepActionListener) {
            this.sweepEngineCallBack = sweepEngineCallBack;
            switch (level) {
                case 1:
                    SweepEngineKit.this.height = 9;
                    SweepEngineKit.this.width = 9;
                    SweepEngineKit.this.boom = 10;
                    break;
                case 2:
                    SweepEngineKit.this.height = 16;
                    SweepEngineKit.this.width = 16;
                    SweepEngineKit.this.boom = 88;
                    break;
                case 3:
                    SweepEngineKit.this.height = 16;
                    SweepEngineKit.this.width = 30;
                    SweepEngineKit.this.boom = 120;
                    break;
                default:
                    sweepEngineCallBack.failure();
                    break;
            }
            SweepEngineKit.this.buttons = new JButton[SweepEngineKit.this.height][SweepEngineKit.this.width];
            this.setBounds(300,100,1500,1000);
            this.setLayout(new GridLayout(SweepEngineKit.this.height, SweepEngineKit.this.width));
            JButton button;
            for (int i = 0; i < SweepEngineKit.this.height; i++) {
                for (int j = 0; j < SweepEngineKit.this.width; j++) {
                    button = new JButton(String.valueOf(j + i * SweepEngineKit.this.width));
                    button.setBackground(Color.GRAY);
                    button.setOpaque(true);
                    button.addActionListener(sweepActionListener);
                    button.setFont(new Font("宋体", 1, 0));
                    this.add(button);
                    SweepEngineKit.this.buttons[i][j] = button;
                }
            }
//            this.pack();
            this.setVisible(true);
//            createMap();
        }
    }
    public class SweepFinalFrame extends JFrame{
    }

    public class SweepActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if("fail".equals(e.getActionCommand()) || "success".equals(e.getActionCommand())){
                sweepFinalFrame.setVisible(false);
                System.exit(0);
                return;
            }
            int n = Integer.parseInt(e.getActionCommand());
            int h = n / SweepEngineKit.this.width;
            int w = n % SweepEngineKit.this.width;
            if(firstClick){
                createMap(h,w);
                firstClick = false;
            }
            if (SweepEngineKit.this.map[h][w] == 1) {
                buttons[h][w].setText("*");
                buttons[h][w].setFont(new Font("宋体", 1, 20));
                sweepEngineCallBack.failure();
            } else {
                DFS(h, w);
                finalNum--;
                if(finalNum==boom){
                    sweepEngineCallBack.success();
                }
            }
        }

    }
    public interface SweepEngineCallBack {
        void success();

        void failure();
    }

    public void showFinalFrame(String text){
        sweepFinalFrame = new SweepFinalFrame();
        sweepFinalFrame.setBounds(1000,500,100,100);
        JButton finalButton = new JButton(text);
        finalButton.addActionListener(sweepActionListener);
        sweepFinalFrame.add(finalButton);
        sweepFinalFrame.setVisible(true);
    }

    public void start(int level) {
        sweepMainFrame = new SweepMainFrame();
        sweepActionListener = new SweepActionListener();
        sweepEngineCallBack = new SweepEngineCallBack() {
            @Override
            public void success() {
                showFinalFrame("success");
            }

            @Override
            public void failure() {
                showFinalFrame("fail");
            }
        };
        sweepMainFrame.init(level, sweepEngineCallBack, sweepActionListener);
    }

    public static void main(String[] args) {
        SweepEngineKit sweepEngineKit = new SweepEngineKit();
        sweepEngineKit.start(2);
    }
}
